package main

import (
	"errors"
	"log"
	"net/http"
)

// 业务系统错误从这里衍生, 衍生时根据情况定义错误的类型
type userError interface {
	error
	Msg() string
	Code() int
}

// AppHandler Handler 类型
type AppHandler func(w http.ResponseWriter, r *http.Request) error

// 包装转换函数
func errWrapper(handler AppHandler) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if err := handler(w, r); err != nil {
			var userErr userError
			if errors.As(err, &userErr) {
				// 1.业务逻辑错误处理   <---------------
				return
			}

			// 2.其它系统错误处理  <-----------------

			panic(err) // 不可预期的
		}
	}
}

func pong(w http.ResponseWriter, r *http.Request) error {
	auth := r.Header.Get("Authorization")
	if auth == "" { // 所有错误直接返回, 不再业务编码时候做
		return errors.New(http.StatusText(http.StatusUnauthorized))
	}
	_, err := w.Write([]byte("pong"))
	if err != nil {
		return err
	}
	return nil
}

func main() {
	http.HandleFunc("/ping", errWrapper(pong))
	log.Fatalln(http.ListenAndServe(":8080", nil))
}
